package com.example.houseitemmanagebackend.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.houseitemmanagebackend.dto.ItemDTO;
import com.example.houseitemmanagebackend.dto.ItemQueryDTO;
import com.example.houseitemmanagebackend.security.JwtUserDetails;
import com.example.houseitemmanagebackend.service.ItemService;
import com.example.houseitemmanagebackend.vo.ItemVO;
import com.example.houseitemmanagebackend.vo.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;

/**
 * 物品管理控制器
 */
@Tag(name = "物品管理", description = "物品管理相关接口")
@RestController
@RequestMapping("/items")
public class ItemController {

    @Autowired
    private ItemService itemService;

    @Operation(summary = "添加物品", description = "添加物品接口")
    @PostMapping
    public Result<Void> addItem(@Valid @RequestBody ItemDTO itemDTO,
            @AuthenticationPrincipal JwtUserDetails userDetails) {
        itemService.addItem(itemDTO);
        return Result.success();
    }

    @Operation(summary = "更新物品", description = "更新物品接口")
    @PutMapping("/{id}")
    public Result<Void> updateItem(@PathVariable Integer id,
            @Valid @RequestBody ItemDTO itemDTO,
            @AuthenticationPrincipal JwtUserDetails userDetails) {
        itemDTO.setId(id);
        itemService.updateItem(itemDTO, userDetails.getId());
        return Result.success();
    }

    @Operation(summary = "删除物品", description = "删除物品接口")
    @DeleteMapping("/{id}")
    public Result<Void> deleteItem(@PathVariable Integer id,
            @AuthenticationPrincipal JwtUserDetails userDetails) {
        itemService.deleteItem(id, userDetails.getId());
        return Result.success();
    }

    @Operation(summary = "获取物品详情", description = "根据ID获取物品详情")
    @GetMapping("/{id}")
    public Result<ItemVO> getItem(@PathVariable Integer id,
            @AuthenticationPrincipal JwtUserDetails userDetails) {
        return Result.success(itemService.getItemById(id, userDetails.getId()));
    }

    @Operation(summary = "分页查询物品列表", description = "分页查询物品列表接口")
    @GetMapping
    public Result<IPage<ItemVO>> getItemPage(
            ItemQueryDTO queryDTO,
            @RequestParam(required = false) Integer pageSize,
            @RequestParam(required = false) String sortBy,
            @RequestParam(required = false) String sortOrder,
            @AuthenticationPrincipal JwtUserDetails userDetails) {
        // 如果提供了pageSize参数，则覆盖queryDTO中的size值
        if (pageSize != null) {
            queryDTO.setSize(pageSize);
        }

        // 处理排序字段
        if (sortBy != null) {
            queryDTO.setSortField(sortBy);
        }

        // 处理排序方向
        if (sortOrder != null) {
            // desc表示降序，其他值如asc表示升序
            queryDTO.setSortDesc("desc".equalsIgnoreCase(sortOrder));
        }

        return Result.success(itemService.getItemPage(queryDTO));
    }

    @Operation(summary = "获取所有物品数据", description = "获取所有物品数据，不分页，用于库存管理视图")
    @GetMapping("/all")
    public Result<List<ItemVO>> getAllItems(
            @RequestParam(required = false) Integer locationId,
            @AuthenticationPrincipal JwtUserDetails userDetails) {
        return Result.success(itemService.getAllItems(locationId, userDetails.getId()));
    }

    /**
     * 导入物品数据
     */
    @PostMapping("/import")
    @Operation(summary = "导入物品数据", description = "通过Excel或CSV文件批量导入物品数据")
    @PreAuthorize("isAuthenticated()")
    public Result<Map<String, Object>> importItems(
            @Parameter(description = "文件") @RequestParam("file") MultipartFile file,
            @Parameter(description = "位置ID") @RequestParam(required = false) Integer locationId,
            @AuthenticationPrincipal JwtUserDetails userDetails) {
        Map<String, Object> result = itemService.importItems(file, locationId, userDetails.getId());
        return Result.success(result);
    }

    /**
     * 导出物品数据
     */
    @GetMapping("/export")
    @Operation(summary = "导出物品数据", description = "导出物品数据到Excel或CSV文件")
    @PreAuthorize("isAuthenticated()")
    public ResponseEntity<Resource> exportItems(
            @Parameter(description = "位置ID") @RequestParam(required = false) Integer locationId,
            @Parameter(description = "导出格式, excel或csv") @RequestParam(defaultValue = "excel") String format,
            @Parameter(description = "是否包含库存信息") @RequestParam(defaultValue = "true") Boolean includeStock,
            @Parameter(description = "是否包含过期信息") @RequestParam(defaultValue = "true") Boolean includeExpired,
            @Parameter(description = "是否包含分类信息") @RequestParam(defaultValue = "true") Boolean includeCategories,
            @AuthenticationPrincipal JwtUserDetails userDetails) {
        Resource resource = itemService.exportItems(locationId, format, includeStock, includeExpired, includeCategories,
                userDetails.getId());

        String filename = "物品清单_" + LocalDate.now() + ("excel".equalsIgnoreCase(format) ? ".xlsx" : ".csv");
        String encodedFilename = URLEncoder.encode(filename, StandardCharsets.UTF_8).replaceAll("\\+", "%20");

        String contentType = "excel".equalsIgnoreCase(format)
                ? "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                : "text/csv;charset=UTF-8";

        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(contentType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedFilename)
                .body(resource);
    }
}